From 6f81c10a54833b4a449b1e3131689225dde85ca3 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 11 Sep 2003 21:02:24 +0000 Subject: [PATCH] Add table menu tests. 2003-09-11 Matthias Clasen * tests/testgtk.c: Add table menu tests. * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the GtkMenuPrivate struct itself. Pointed out by valgrind. * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up properly. (#121998) --- ChangeLog | 10 +++ ChangeLog.pre-2-10 | 10 +++ ChangeLog.pre-2-4 | 10 +++ ChangeLog.pre-2-6 | 10 +++ ChangeLog.pre-2-8 | 10 +++ gtk/gtkmenu.c | 40 ++++++++++- gtk/gtkuimanager.c | 89 ++++++++++++++++--------- tests/testgtk.c | 163 +++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 311 insertions(+), 31 deletions(-) diff --git a/ChangeLog b/ChangeLog index 948c073442..c08bc63fed 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2003-09-11 Matthias Clasen + + * tests/testgtk.c: Add table menu tests. + + * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the + GtkMenuPrivate struct itself. Pointed out by valgrind. + + * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up + properly. (#121998) + Wed Sep 10 22:25:04 2003 Kristian Rietveld The table menu patch! Turns GtkMenu into a table, so you can attach diff --git a/ChangeLog.pre-2-10 b/ChangeLog.pre-2-10 index 948c073442..c08bc63fed 100644 --- a/ChangeLog.pre-2-10 +++ b/ChangeLog.pre-2-10 @@ -1,3 +1,13 @@ +2003-09-11 Matthias Clasen + + * tests/testgtk.c: Add table menu tests. + + * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the + GtkMenuPrivate struct itself. Pointed out by valgrind. + + * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up + properly. (#121998) + Wed Sep 10 22:25:04 2003 Kristian Rietveld The table menu patch! Turns GtkMenu into a table, so you can attach diff --git a/ChangeLog.pre-2-4 b/ChangeLog.pre-2-4 index 948c073442..c08bc63fed 100644 --- a/ChangeLog.pre-2-4 +++ b/ChangeLog.pre-2-4 @@ -1,3 +1,13 @@ +2003-09-11 Matthias Clasen + + * tests/testgtk.c: Add table menu tests. + + * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the + GtkMenuPrivate struct itself. Pointed out by valgrind. + + * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up + properly. (#121998) + Wed Sep 10 22:25:04 2003 Kristian Rietveld The table menu patch! Turns GtkMenu into a table, so you can attach diff --git a/ChangeLog.pre-2-6 b/ChangeLog.pre-2-6 index 948c073442..c08bc63fed 100644 --- a/ChangeLog.pre-2-6 +++ b/ChangeLog.pre-2-6 @@ -1,3 +1,13 @@ +2003-09-11 Matthias Clasen + + * tests/testgtk.c: Add table menu tests. + + * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the + GtkMenuPrivate struct itself. Pointed out by valgrind. + + * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up + properly. (#121998) + Wed Sep 10 22:25:04 2003 Kristian Rietveld The table menu patch! Turns GtkMenu into a table, so you can attach diff --git a/ChangeLog.pre-2-8 b/ChangeLog.pre-2-8 index 948c073442..c08bc63fed 100644 --- a/ChangeLog.pre-2-8 +++ b/ChangeLog.pre-2-8 @@ -1,3 +1,13 @@ +2003-09-11 Matthias Clasen + + * tests/testgtk.c: Add table menu tests. + + * gtk/gtkmenu.c (gtk_menu_free_private): Don't forget to free the + GtkMenuPrivate struct itself. Pointed out by valgrind. + + * gtk/gtkuimanager.c (gtk_ui_manager_finalize): Clean up + properly. (#121998) + Wed Sep 10 22:25:04 2003 Kristian Rietveld The table menu patch! Turns GtkMenu into a table, so you can attach diff --git a/gtk/gtkmenu.c b/gtk/gtkmenu.c index 0de9785496..ed0b2e3a38 100644 --- a/gtk/gtkmenu.c +++ b/gtk/gtkmenu.c @@ -28,6 +28,7 @@ #include /* memset */ #include "gdk/gdkkeysyms.h" +#include "gtkaccellabel.h" #include "gtkaccelmap.h" #include "gtkbindings.h" #include "gtklabel.h" @@ -226,6 +227,8 @@ gtk_menu_free_private (gpointer data) GtkMenuPrivate *priv = (GtkMenuPrivate *)data; g_free (priv->heights); + + g_free (priv); } GtkMenuPrivate * @@ -2303,6 +2306,41 @@ gtk_menu_button_release (GtkWidget *widget, return GTK_WIDGET_CLASS (parent_class)->button_release_event (widget, event); } +static const gchar * +get_accel_path (GtkWidget *menu_item, + gboolean *locked) +{ + const gchar *path; + GtkWidget *label; + GClosure *accel_closure; + GtkAccelGroup *accel_group; + + path = _gtk_widget_get_accel_path (menu_item, locked); + if (!path) + { + path = GTK_MENU_ITEM (menu_item)->accel_path; + + if (locked) + { + *locked = TRUE; + + label = GTK_BIN (menu_item)->child; + + if (GTK_IS_ACCEL_LABEL (label)) + { + g_object_get (label, + "accel_closure", &accel_closure, + NULL); + accel_group = gtk_accel_group_from_accel_closure (accel_closure); + + *locked = accel_group->lock_count > 0; + } + } + } + + return path; +} + static gboolean gtk_menu_key_press (GtkWidget *widget, GdkEventKey *event) @@ -2397,7 +2435,7 @@ gtk_menu_key_press (GtkWidget *widget, gboolean locked, replace_accels = TRUE; const gchar *path; - path = _gtk_widget_get_accel_path (menu_item, &locked); + path = get_accel_path (menu_item, &locked); if (!path || locked) { /* can't change accelerators on menu_items without paths diff --git a/gtk/gtkuimanager.c b/gtk/gtkuimanager.c index d03f3006e8..03a978dbd9 100644 --- a/gtk/gtkuimanager.c +++ b/gtk/gtkuimanager.c @@ -64,7 +64,7 @@ typedef struct _Node Node; struct _Node { NodeType type; - const gchar *name; + gchar *name; GQuark action_name; GtkAction *action; @@ -126,6 +126,7 @@ static GNode *get_node (GtkUIManager *self, const gchar *path, NodeType node_type, gboolean create); +static gboolean free_node (GNode *node); static void node_prepend_ui_reference (Node *node, guint merge_id, @@ -269,10 +270,9 @@ gtk_ui_manager_init (GtkUIManager *self) self->private_data->last_merge_id = 0; self->private_data->add_tearoffs = FALSE; - merge_id = gtk_ui_manager_new_merge_id (self); - node = get_child_node (self, NULL, "ui", 4, - NODE_TYPE_ROOT, TRUE, FALSE); + node = get_child_node (self, NULL, "ui", 2, + NODE_TYPE_ROOT, TRUE, FALSE); node_prepend_ui_reference (NODE_INFO (node), merge_id, 0); } @@ -286,6 +286,20 @@ gtk_ui_manager_finalize (GObject *object) g_source_remove (self->private_data->update_tag); self->private_data->update_tag = 0; } + + g_node_traverse (self->private_data->root_node, + G_POST_ORDER, G_TRAVERSE_ALL, -1, + (GNodeTraverseFunc)free_node, 0); + g_node_destroy (self->private_data->root_node); + self->private_data->root_node = NULL; + + g_list_foreach (self->private_data->action_groups, + (GFunc) g_object_unref, NULL); + g_list_free (self->private_data->action_groups); + self->private_data->action_groups = NULL; + + g_object_unref (self->private_data->accel_group); + self->private_data->accel_group = NULL; } static void @@ -462,7 +476,7 @@ gtk_ui_manager_remove_action_group (GtkUIManager *self, * Since: 2.4 **/ GList * -gtk_ui_manager_get_action_groups (GtkUIManager *self) +gtk_ui_manager_get_action_groups (GtkUIManager *self) { g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL); @@ -480,7 +494,7 @@ gtk_ui_manager_get_action_groups (GtkUIManager *self) * Since: 2.4 **/ GtkAccelGroup * -gtk_ui_manager_get_accel_group (GtkUIManager *self) +gtk_ui_manager_get_accel_group (GtkUIManager *self) { g_return_val_if_fail (GTK_IS_UI_MANAGER (self), NULL); @@ -538,8 +552,8 @@ gtk_ui_manager_get_widget (GtkUIManager *self, * Since: 2.4 **/ GtkAction * -gtk_ui_manager_get_action (GtkUIManager *self, - const gchar *path) +gtk_ui_manager_get_action (GtkUIManager *self, + const gchar *path) { GNode *node; @@ -559,13 +573,13 @@ gtk_ui_manager_get_action (GtkUIManager *self, } static GNode * -get_child_node (GtkUIManager *self, - GNode *parent, - const gchar *childname, - gint childname_length, - NodeType node_type, - gboolean create, - gboolean top) +get_child_node (GtkUIManager *self, + GNode *parent, + const gchar *childname, + gint childname_length, + NodeType node_type, + gboolean create, + gboolean top) { GNode *child = NULL; @@ -644,10 +658,10 @@ get_child_node (GtkUIManager *self, } static GNode * -get_node (GtkUIManager *self, - const gchar *path, - NodeType node_type, - gboolean create) +get_node (GtkUIManager *self, + const gchar *path, + NodeType node_type, + gboolean create) { const gchar *pos, *end; GNode *parent, *node; @@ -677,9 +691,26 @@ get_node (GtkUIManager *self, if (node != NULL && NODE_INFO (node)->type == NODE_TYPE_UNDECIDED) NODE_INFO (node)->type = node_type; + return node; } +static gboolean +free_node (GNode *node) +{ + Node *info = NODE_INFO (node); + + g_list_foreach (info->uifiles, (GFunc) g_free, NULL); + g_list_free (info->uifiles); + + if (info->action) + g_object_unref (info->action); + g_free (info->name); + g_chunk_free (info, merge_node_chunk); + + return FALSE; +} + /** * gtk_ui_manager_new_merge_id: * @self: a #GtkUIManager @@ -700,9 +731,9 @@ gtk_ui_manager_new_merge_id (GtkUIManager *self) } static void -node_prepend_ui_reference (Node *node, - guint merge_id, - GQuark action_quark) +node_prepend_ui_reference (Node *node, + guint merge_id, + GQuark action_quark) { NodeUIReference *reference; @@ -717,8 +748,8 @@ node_prepend_ui_reference (Node *node, } static void -node_remove_ui_reference (Node *node, - guint merge_id) +node_remove_ui_reference (Node *node, + guint merge_id) { GList *p; @@ -1900,11 +1931,9 @@ update_node (GtkUIManager *self, { if (info->proxy) gtk_widget_destroy (info->proxy); - if ((info->type == NODE_TYPE_MENU_PLACEHOLDER || - info->type == NODE_TYPE_TOOLBAR_PLACEHOLDER) && - info->extra) + if (info->extra) gtk_widget_destroy (info->extra); - g_chunk_free (info, merge_node_chunk); + free_node (node); g_node_destroy (node); } } @@ -2056,8 +2085,8 @@ print_node (GtkUIManager *self, * * Since: 2.4 **/ -gchar* -gtk_ui_manager_get_ui (GtkUIManager *self) +gchar * +gtk_ui_manager_get_ui (GtkUIManager *self) { GString *buffer; diff --git a/tests/testgtk.c b/tests/testgtk.c index 4c0ef6bde7..52f60125d6 100644 --- a/tests/testgtk.c +++ b/tests/testgtk.c @@ -3465,6 +3465,162 @@ create_menu (GdkScreen *screen, gint depth, gint length, gboolean tearoff) return menu; } +static GtkWidget* +create_table_menu (GdkScreen *screen, gint cols, gint rows, gboolean tearoff) +{ + GtkWidget *menu; + GtkWidget *menuitem; + GtkWidget *submenu; + GtkWidget *image; + char buf[32]; + int i, j; + + menu = gtk_menu_new (); + gtk_menu_set_screen (GTK_MENU (menu), screen); + + j = 0; + if (tearoff) + { + menuitem = gtk_tearoff_menu_item_new (); + gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1); + gtk_widget_show (menuitem); + j++; + } + + menuitem = gtk_menu_item_new_with_label ("items"); + gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1); + + submenu = gtk_menu_new (); + gtk_menu_set_screen (GTK_MENU (submenu), screen); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); + gtk_widget_show (menuitem); + j++; + + /* now fill the items submenu */ + image = gtk_image_new_from_stock (GTK_STOCK_HELP, + GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + menuitem = gtk_image_menu_item_new_with_label ("Image"); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 0, 1); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 2); + gtk_widget_show (menuitem); + + image = gtk_image_new_from_stock (GTK_STOCK_HELP, + GTK_ICON_SIZE_MENU); + gtk_widget_show (image); + menuitem = gtk_image_menu_item_new_with_label ("Image"); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2); + gtk_widget_show (menuitem); + + menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 2, 3); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 2, 3); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 3, 4); + gtk_widget_show (menuitem); + + menuitem = gtk_radio_menu_item_new_with_label (NULL, "Radio"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 3, 4); + gtk_widget_show (menuitem); + + menuitem = gtk_check_menu_item_new_with_label ("Check"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 4, 5); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 4, 5); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("x"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 5, 6); + gtk_widget_show (menuitem); + + menuitem = gtk_check_menu_item_new_with_label ("Check"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 5, 6); + gtk_widget_show (menuitem); + /* end of items submenu */ + + menuitem = gtk_menu_item_new_with_label ("spanning"); + gtk_menu_attach (GTK_MENU (menu), menuitem, 0, cols, j, j + 1); + + submenu = gtk_menu_new (); + gtk_menu_set_screen (GTK_MENU (submenu), screen); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); + gtk_widget_show (menuitem); + j++; + + /* now fill the spanning submenu */ + menuitem = gtk_menu_item_new_with_label ("a"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 2, 0, 1); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("b"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 2, 3, 0, 2); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("c"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 1, 3); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("d"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 2, 1, 2); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("e"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 1, 3, 2, 3); + gtk_widget_show (menuitem); + /* end of spanning submenu */ + + menuitem = gtk_menu_item_new_with_label ("left"); + gtk_menu_attach (GTK_MENU (menu), menuitem, 0, 1, j, j + 1); + submenu = gtk_menu_new (); + gtk_menu_set_screen (GTK_MENU (submenu), screen); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("Empty"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("right"); + gtk_menu_attach (GTK_MENU (menu), menuitem, 1, 2, j, j + 1); + submenu = gtk_menu_new (); + gtk_menu_set_screen (GTK_MENU (submenu), screen); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu); + gtk_widget_show (menuitem); + + menuitem = gtk_menu_item_new_with_label ("Empty"); + gtk_menu_attach (GTK_MENU (submenu), menuitem, 0, 1, 0, 1); + gtk_widget_show (menuitem); + + j++; + + for (; j < rows; j++) + for (i = 0; i < cols; i++) + { + sprintf (buf, "(%d %d)", i, j); + menuitem = gtk_menu_item_new_with_label (buf); + gtk_menu_attach (GTK_MENU (menu), menuitem, i, i + 1, j, j + 1); + gtk_widget_show (menuitem); + } + + return menu; +} + static void create_menus (GtkWidget *widget) { @@ -3516,6 +3672,13 @@ create_menus (GtkWidget *widget) gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu); gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); gtk_widget_show (menuitem); + + menu = create_table_menu (screen, 2, 50, TRUE); + + menuitem = gtk_menu_item_new_with_label ("table"); + gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), menu); + gtk_menu_shell_append (GTK_MENU_SHELL (menubar), menuitem); + gtk_widget_show (menuitem); menuitem = gtk_menu_item_new_with_label ("foo"); gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), create_menu (screen, 3, 5, TRUE)); -- 2.30.2